﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Exercise2
{
    class Program
    {
        static void Main(string[] o)
        {
            var lbl = new Label { Location = new System.Drawing.Point(0, 0) };
            var txt = new TextBox { Location = new System.Drawing.Point(0, 50) };
            var frm = new Form
            {
                Controls = { lbl, txt }
            };

            var txtChangeEvents = TxtChangeEventsToSequenceOfEvents(txt);
            var mouseMoveEvents = MouseMoveEventsToSequenceOfEvents(frm);


            using (txtChangeEvents.Subscribe(LogTextChanged))
            using (mouseMoveEvents.Subscribe(eventArgs => LogMousePosition(eventArgs, lbl)))
            {
                Application.Run(frm);
            }
        }

        private static IObservable<MouseEventArgs> MouseMoveEventsToSequenceOfEvents(Form frm)
        {
            //event is mouse move
            return Observable.FromEvent<MouseEventArgs>(
                eventHandler => frm.MouseMove += (s, e) => eventHandler(e),
                eventHandler => frm.MouseMove -= (s, e) => eventHandler(e));
            //return Observable.FromEventPattern<MouseEventArgs>(frm, "MouseMove");
        }

        private static IObservable<string> TxtChangeEventsToSequenceOfEvents(TextBox txt)
        {
            return (from evt in Observable.FromEventPattern<EventArgs>(txt, "TextChanged")
                    select ((TextBox)evt.Sender).Text)
                .Timestamp()
                .Do(inp => Console.WriteLine("I: " + inp.Timestamp.Millisecond + " - " + inp.Value))
                .Select(x => x.Value)
                .Throttle(TimeSpan.FromSeconds(1))
                .Timestamp()
                .Do(inp => Console.WriteLine("T: " + inp.Timestamp.Millisecond + " - " + inp.Value))
                .Select(x => x.Value)
                .DistinctUntilChanged();
        }

        private static void LogMousePosition(MouseEventArgs @event, Label lbl)
        {
            lbl.Text = @event.Location.ToString();
        }

        private static void LogTextChanged(string txtValue)
        {
            Console.WriteLine("User wrote: " + txtValue);
        }
    }
}
